package jabachat;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.Socket;
import java.net.URL;

public class NullChatClient implements Runnable, ChatClient {
// TODO занести сюда типы сообщений!
    String token = null;
    Socket s = null;
    Socket ss = null;
    byte buf[] = new byte[64 * 1024];
    ChatUI UI;
    byte size[] = new byte[2];
    byte cmd[] = new byte[1];
    byte data[];
    URL handshakeURL;
    String chatIP;
    public int received = 0;
    public int posted = 0;
    public static final int STATE_NONE = 0;
    public static final int STATE_CONNECTING = 1;
    public static final int STATE_HANDSHAKING = 1;
    public static final int STATE_CONNECTED = 2;
    private int stateCurrent = STATE_NONE;

    public NullChatClient(ChatUI ui, String handshakeURL, String chatIP) throws MalformedURLException {
        this.handshakeURL = new URL(handshakeURL);
        this.chatIP = chatIP;
        this.UI = ui;

    }

    private void setUp() {
        try {
            s = new Socket(chatIP, 1984);
            //   ss = new Socket(handshakeURL, 1985);
        } catch (Exception e) {
            System.out.println(e.toString());
        }

    }

    @Override
    public void connect() {
        try {
            setState(STATE_CONNECTING);
            UI.message("Connecting...", 0);
            String received = new String(buf, 0, handshakeURL.openStream().read(buf));

            //  String received = new String(buf, 0, ss.getInputStream().read(buf));
            System.out.println(received);

            int tStart = received.indexOf("token=", 0) + 6;
            int tEnd = tStart + 32;
            token = received.substring(tStart, tEnd).trim();
            String handshake = "<handshake version=4 token=" + token + "/>";
            System.out.println(handshake);
            UI.message("Handshaking...", 0);
            send(handshake);

            receive();
        } catch (Exception e) {
            System.out.println(e.toString());
        }
    }

    public void disconnect() {
        try {
            s.close();
        } catch (IOException ex) {
        }
        setState(STATE_NONE);
    }

    private synchronized void setState(int state) {
        stateCurrent = state;
    }

    public synchronized int getState(int state) {
        return stateCurrent;
    }

//    private int getPostcount(){}
    private void receive() {
        setState(STATE_CONNECTED);

        while (true) {
            try {
                s.getInputStream().read(size, 0, 2);
                s.getInputStream().read(cmd, 0, 1);

                int i_size = ((int) size[0] & 0xff) << 8;
                i_size += (int) size[1] & 0xff;

                byte data[] = readAll(s.getInputStream(), i_size);

                String reply = new String(data, 0, data.length, "utf-8");

                switch (cmd[0]) {
                    case 0x01: {
                        received++;
                        UI.message(reply, 1);  //post
                        break;
                    }
                    case 0x05: {
                        UI.message(reply, 5);  //captcha
                        break;
                    }
                    case 0x04: {
                        UI.message(reply, 4);  //radio
                        break;
                    }
                    case 0x02: {
                        UI.message(reply, 2);  //online
                        break;
                    }
                    default: {
                        UI.message(reply, 0);  //post
                        break;
                    }
                }
            } catch (Exception e) {
                System.out.println(e.toString());
            }
        }

    }

    public static byte[] readAll(InputStream is, int size) throws IOException {
        byte[] data = new byte[size];
        int i = is.read(data, 0, size);

        while (i < size) {
            int j = size - i;
            j = is.read(data, i, j);
            i += j;
        }
        return data;
    }

    @Override
    public void send(String toSend) {
//        switch (toSend) {
//            case "postcount":
//                toSend="Моё количество сообщений: "+POSTED;
//                break;
//            case "postreceived":
//                toSend="Получено сообщений: "+RECEIVED;
//                break;
//        }
//      

        try {
            s.getOutputStream().write(toSend.getBytes("utf-8"));
            posted++;
        } catch (Exception e) {
            System.err.println(e);
        }

    }

    @Override
    public void run() {
        try {
            setUp();
            connect();
        } catch (Exception ex) {
            System.err.println(ex.toString());
        }
    }
}
